React Hooks vs. Vue Composition API
teamLab は Vue project が多いから、Sample code は Vue 中心に書く
勉強会の内容(社員のみ閲覧可能)
React Hooks 簡単的に説明
Hooks は class を使わずに React state など機能を使える機能だ
Points
使わないでも大丈夫
100% NO breaking changes
React v16.8 から使える
Sample:
code: React Hooks
import React, { useState } from 'react';
function Example() {
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useState だけではなく、useEffect, useContext など色々 API function がある
Vue Composition API 簡単的に説明
Composition API は functional API だ、Vue2, Vue3 両方使える。
Points
ロジック再利用やすい
Type checker やすい(TypeScriptだけではなく、JavaScript もTypeを利用できる)
Vue data binding, lifecycle は使える
Sample:
code:Vue Composition API
<template>
<button @click="increment">Count is: {{ count }}</button>
</template>
<script>
import { ref } from "@vue/composition-api";
export default {
setup() {
const count = ref(0);
function increment() {
count.value++;
}
return {
count,
increment
};
}
};
</script>
React Hooks と Vue Composition API 同じ部分
1. 目的が同じだ、ロジック再利用やすいため、Code 読みやすいため
2. 同じ functional API を採用、this がなくなる
3. 余計な API が増えた
React class API 時代、ロジック再利用方法の一 HoC:
code:hoc
class App extends Component {
}
function hoc(Component) {
return newComponent
}
export default hoc(App)
理解辛い、Code 構造が複雑
Vue class API 時代、ロジック再利用方法の一 Mixins:
code:vue
const MixinA extends Vue {
methods: {
logicA() {
...
}
}
}
export default {
methods: {
logicB() {
...
}
}
}
理解辛い、Code 構造が複雑
Vue Composition API でロジック再利用
code: Vue Composition API
<template>
<div>
<button @click="toggleA">{{ openedA ? 'A': 'x' }}</button>
<button @click="toggleB">{{ openedB ? 'B': 'x' }}</button>
<button @click="toggleC">{{ openedC ? 'C': 'x' }}</button>
<button @click="toggleD">{{ openedD ? 'D': 'x' }}</button>
</div>
</template>
<script>
import { ref } from "@vue/composition-api";
export default {
setup() {
return {
openedA,
toggleA,
openedB,
toggleB,
openedC,
toggleC,
openedD,
toggleD
};
}
};
function useToggle() {
const opened = ref(false);
function toggle() {
opened.value = !opened.value;
}
}
</script>
Vue Composition API ref vs reactive
code:ref vs reactive
// ref
const x = ref(0)
const y = ref(0)
return {x, y}
<template>
<div>{{x}} {{y}} <div>
// reactive
const point = reactive({
x: 0,
y: 0
})
return {point}
<template>
<div>{{point.x}} {{point.y}} </div>
React Hooks と Vue Composition API 違う部分
1. React Hooks に Lifecycle がなくなる、Vue composition API に Lifecycle がまだある
2. React Hooks は普通な function, object、Vue composition API は特別な Object、setup()中に定義が必要
3. React Hooks は Top layer しか使えない、Vue composition API は if for 中にも使える
下記のコードは何か問題があるか?
code:Vue Composition API export
<template>
<div>
<span>{{ count }}</span>
<button @click="increment">+</button>
</div>
</template>
<script>
import { ref } from '@vue/composition-api'
export default {
setup() {
const count = ref(0)
function increment() {
count.value += 1
}
return {count, increment}
},
}
</script>
下記のコードは何か問題があるか?
code:Vue Composition API computed
<template>
<div>
<input v-model="value" type="number" />
<p>{{ double }}</p>
</div>
</template>
<script>
import { ref } from '@vue/composition-api'
export default {
setup() {
const value = ref(0)
const double = computed(() => value.value * 2)
return {
value,
double,
}
},
}
</script>
React Hooks が強い部分
長い return がなし
React Hooks は stateless だ、computed 不要
下記のコードは何か問題があるか?
code: React bad update
import React from 'react';
<Display input={1} />
function Display({ input }) {
// 重い
const calculate = (value) => {
for (let index = 0; index < 200; index++) {
console.log(index);
}
return 2 * value;
};
// useCallback
return (
<p>
// input: 1, out: 2
input: {input}, out: {output}
</p>
);
}
export default Display;
export default React.memo(Display)
Vue Composition API 強い部分
Lint を使わずに開発できる
性能心配が少ない
lifecycle 使える
React Hooks 性能ために雑な APIs
useEffect
useMemo
useCallback
React.memo / PureComponent / shouldComponentUpdate
下記のコードは何か問題があるか?
code:React auto-counter
import React, { useState, useEffect } from "react";
export default function App() {
useEffect(() => {
const id = setInterval(() => {
setCount(count + 1);
}, 1000);
});
return <h1>count: {count}</h1>;
}
質問
onuma.icon setupの中でrefの設定を書いているサンプルコードがよく見られますが、実際の開発では外だししてuse~という感じで使うようにしていた方がいいでしょうか?そっちの方が再利用性を意識できていいような気がしました。
code:javascript
import { ref } from "@vue/composition-api";
// 例え1つしか使わないとしても一応外で定義しておく
function useToggle() {
const opened = ref(false);
function toggle() {
opened.value = !opened.value;
}
}
const App = {
setup() {
return {
opened,
toggle,
};
}
};
export default App;
onuma.icon Composition APIのデメリットについてはどう思いますか?
プログラミング力が試される
お作法がわかりづらそう
自由度が高過ぎてどういう書き方がいいかが分からなそう
実装難易度が更に上がってしまうのではないか?
より設計が難しくなる
今まではdata, methodsと決まっていたのであんまり考えなくてもなんとなくできていたが、上手くモジュール化しないとカオスになりそう
参考